<template>
  <basic-container>
    <avue-crud v-bind="bindVal"
               v-on="onEvent"
               v-model="form"
               ref="crud"
               v-permission="{addBtn: 'SYSTEM_FUNCTION_ADD',editBtn: 'SYSTEM_FUNCTION_UPDATE',delBtn: 'SYSTEM_FUNCTION_DELETE'}"
               @tree-load="treeLoad"
               :before-open="beforeOpen"
               :search.sync="searchFrom">
      <template slot="target" slot-scope="scope">
        <el-tag>{{scope.row.targetStr}}</el-tag>
      </template>

      <template slot="functionType" slot-scope="scope">
        <el-tag :type="scope.row.functionType===0?'warning':scope.row.functionType===2?'success':''">{{scope.row.$functionType}}</el-tag>
      </template>

      <template slot="parentIdFormType" slot-scope="{item,value,label}">
        <span class="custom-tree-node">
              <span>{{ item[label] }}</span>
              <span>
                <el-tag size="mini" :type="item.functionType===0?'warning':'text'">{{item.functionType===0?'按钮':'菜单'}}</el-tag>
              </span>
            </span>
      </template>

      <template slot="isHide" slot-scope="scope">

        <el-switch
            v-permission="'SYSTEM_FUNCTION_HIDE'"
            v-if="scope.row.functionType === 1"
            @change="editHide(scope.row)"
            v-model="scope.row.isHide" >
        </el-switch>

        <el-tag v-permission="'!SYSTEM_FUNCTION_HIDE'" v-if="scope.row.functionType === 1" :type="scope.row.isHide?'warning':''">{{scope.row.isHide?'是':'否'}}</el-tag>

      </template>

      <template slot="icon" slot-scope="scope">
        <i :class="scope.row.icon"></i>
      </template>

      <template slot="menuLeft" slot-scope="{}">
        <el-button type="success" v-permission="'SYSTEM_FUNCTION_GENERATE'" icon="el-icon-refresh" size="small" @click.stop="generate()">同  步</el-button>
        <el-button type="danger" v-permission="'SYSTEM_FUNCTION_DELETE'" icon="el-icon-delete" size="small" @click.stop="deletes()">批量删除</el-button>
        <el-button plain v-permission="'SYSTEM_FUNCTION_HIERARCHY'" icon="el-icon-sort" size="small" @click.stop="showHierarchy()">设置层级</el-button>
      </template>

      <template slot="menuRight" slot-scope="{size}">

        <avue-select v-model="clientId"
                     placeholder="客户端过滤"
                     :clearable="false"
                     style="margin-right: 5px;width: 40%!important;"
                     type="tree"
                     :props="{label: 'name',value: 'id'}"
                     :dic="clientList"
                     :size="size"></avue-select>

        <avue-select v-model="menuId"
                     placeholder="顶级菜单过滤"
                     style="margin-right: 5px;width: 30%!important;"
                     type="tree"
                     :props="{label: 'name',value: 'id'}"
                     :dic="menuList"
                     :size="size"></avue-select>

      </template>

      <template slot="menu"
                slot-scope="scope">
        <el-button type="text"
                          icon="el-icon-plus"
                          v-permission="'SYSTEM_FUNCTION_ADD'"
                          v-if="scope.row.functionType === 1 || scope.row.functionType === 0"
                          @click="handleAdd(scope.row,scope.index)"
                          size="small">新增子项
        </el-button>
      </template>
    </avue-crud>

    <el-dialog custom-class="avue-dialog" class="avue-dialog" title="设置层级"
               v-dialogDrag
               :close-on-click-modal="false"
               width="400px"
               append-to-body
               :visible.sync="hierarchyBox">

      <el-button type="text" @click="expandedAll(true)">全部展开</el-button>
      <el-button type="text" @click="expandedAll(false)">全部折叠</el-button>

      <avue-tree :data="this.treeFunctionList"
                 :option="{nodeKey: 'id',
                 filterText:'请输入关键字进行搜索',
                 defaultExpandAll: false,
                 defaultExpandedKeys: ['-1'],
                 multiple:true,
                 checkStrictly: true,
                 menu: false,
                 props:{label: 'functionName',value: 'id'},
                 addBtn: false}"
                 :style="styleName"
                 check-on-click-node
                 highlight-current
                 node-key="id"
                 ref="treeFunction"
                 @check-change="treeHierarchyCheck">
            <span class="custom-tree-node" slot-scope="{ node, data }">
              <span>{{ node.label }}</span>
              <span>
                <el-tag size="mini" :type="data.functionType===0?'warning':'text'">{{data.functionType===0?'按钮':'菜单'}}</el-tag>
              </span>
            </span>
      </avue-tree>

      <span slot="footer" class="avue-dialog__footer">
              <el-button @click="hierarchyBox = false">取 消</el-button>
              <el-button type="primary" @click="saveHierarchy">确 定</el-button>
          </span>
    </el-dialog>

  </basic-container>
</template>

<script>

import {addItemById, delItemById, treeAddDisabled, treeAddObj} from "@/util/util";
import {validatenull} from "@/util/validate";
import func from "@/util/func";

export default window.$crudCommon({
  data () {
    return {
      heightCalc: 519,
      height: 0,
      clientId: '',
      clientList: [],
      menuId: '',
      menuList: [],
      searchFrom: {},
      oldEditForm: {},
      hierarchyBox: false,
      treeFunctionList: []
    }
  },
  created () {
    this.api['clientList']().then(res => {

      if (validatenull(res.data.data)){
        this.$message.error('请先新建客户端');
        return;
      }

      this.clientList = res.data.data;
      this.clientId = res.data.data[0].id;
      // setTimeout(()=>{
      //   this.$refs.crud.updateDic('parentId');
      // },0)
    });

  },
  watch: {
    'clientId'(val){
      this.getList();

      this.menuId = '';

      this.api['menuList'](val).then(res => {
        this.function = res.data.data;
      });
    },
    'menuId'(){
      this.getList();
    }
  },
  computed: {
    styleName() {
      return {
        height: this.height + 'px'
      }
    }
  },
  mounted() {
    this.height = document.documentElement.clientHeight - this.heightCalc;
  },
  methods: {
    generate(){
      this.$confirm("确定要同步所有接口按钮吗?", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning"
      })
      .then(() => {
        this.api['generate']().then(() => {
          this.$message({
            type: "success",
            message: "操作成功!"
          });
          this.getList();
        })
      });

    },
    treeLoad(tree, treeNode, resolve){
      this.api[this.option.list || 'list']({parentId_eq: tree.id,clientId_eq: this.clientId}).then(res => {
        let list = res.data.data;
        list.forEach(ele => {
          ele.children = [];
        });
        resolve(list);
      });
    },
    listBefore(done){
      if (this.clientId){
        this.params.clientId_eq = this.clientId;
      }
      this.params.menuId_eq = this.menuId;
      done();
    },
    addBefore(done){
      this.form.clientId = this.clientId;
      done();
    },
    handleAdd (row) {
      this.form.parentId = row.id;
      this.$refs.crud.rowAdd();
    },
    beforeOpen(done,type){

      if (["add"].includes(type)) {
        if(validatenull(this.clientId)){
          this.$message.error('请先新建客户端');
          return;
        }
      }

      if (["edit"].includes(type)) {
        this.oldEditForm = this.form;
      }
      done();
    },
    addAfter (row, done, data) {
      done(Object.assign(row, {
        id: data.data,
        children: []
      }));
      this.$message.success('新增成功');
      this.$refs.crud.updateDic('parentId');
    },
    updateAfter (row, done) {
      this.$refs.crud.DIC.functionType.forEach(dic=>{
        if (dic.code === row.functionType){
          if (!row.params){
            row.params = {};
          }
          row.params.functionType = dic.name;
        }
      })
      done(row);
      this.$message.success('修改成功');
      if (row.functionType === 1){
        this.$refs.crud.updateDic('parentId');
      }

      //动态改变结构
      if (this.oldEditForm.parentId !== row.parentId){
        if (row.parentId === undefined){
          row.parentId = '-1';
        }
        const data = delItemById(this.$refs.crud.data,row.id);

        if (data){
          //avue更新后会丢失箭头，所以我这里不管改没改上级ID，都去修改下；
          const index = this.oldEditForm.parentId !== row.parentId ? 0 : data.index;
          addItemById(this.$refs.crud.data,Object.assign(data.data, row),index);
        }
      }

    },
    delAfter (row, done) {
      done(row);
      this.$message.success('删除成功');
      if (row.functionType === 1){
        this.$refs.crud.updateDic('parentId');
      }
    },
    delsAfter (ids) {
      func.split(ids).forEach(id => {
        delItemById(this.$refs.crud.data,id);
      })
      this.$message.success('删除成功');
      this.$refs.crud.updateDic('parentId');
    },
    editHide(row){
      this.api['hide'](row.id,row.isHide).then((res) => {
        if (!res.data.status){
          row.isHide = !row.isHide;
        }
      }).catch(() =>{
        row.isHide = !row.isHide;
      })
    },
    treeHierarchyCheck(node,is){
      if (is) {
        //单选实现
        this.$refs.treeFunction.setCheckedKeys([node.id]);
      }
    },
    showHierarchy(){

      if (this.selection.length > 0){
        this.api['treeHierarchy']({clientId: this.clientId}).then(res => {

          const data = res.data.data;

          treeAddDisabled(data || [], this.selection.map(item => item.id));

          // 如果包含菜单则不能选按钮
          const isMenu = this.selection.some(item => {
            return item.functionType === 1;
          });
          if (isMenu){
            treeAddObj(data || [], {'disabled':true}, (data)=>{
              return data.functionType === 0
            });
          }

          this.treeFunctionList = [ {
            id: "-1",
            functionName: "顶级",
            hasChildren: true,
            // 按钮和接口不可设置到顶级
            disabled : this.selection.some(item => {
              return item.functionType === 0 || item.functionType === 2;
            }),
            children: data
          }];

          this.hierarchyBox = true;
          if (this.$refs.treeFunction){
            this.$refs.treeFunction.setCheckedKeys([]);
          }
        });
      }else{
        this.$message.warning("至少选中一条数据");
      }

    },
    expandedAll(expanded){
      let nodes = this.$refs.treeFunction.$refs.tree.store.nodesMap;
      for (const id in nodes) {
        nodes[id].expanded = expanded;
      }
      nodes["-1"].expanded = true;
    },
    saveHierarchy(){

      let selectId = this.$refs.treeFunction.getCheckedKeys()[0];
      if (this.validatenull(selectId)){
        this.hierarchyBox = false;
        return;
      }

      let ids = this.selection.map(item => {
        return item.id;
      }).join(',');

      this.api['saveHierarchy'](ids,selectId).then(res=>{
        if (res.data.status){
          this.$message({
            type: "success",
            message: "设置成功!"
          });
          this.getList();
          this.hierarchyBox = false;
        }else {
          this.$message({
            type: "error",
            message: "设置失败!"
          });
        }
      });
    }
  }
}, {
  onLoad: false,
  name: '/system/function',
  res: (data) => {
    return {
      data: data.data
    }
  },
  crudPage: false
})
</script>

<style lang="scss" scoped>
.custom-tree-node {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-size: 14px;
  padding-right: 10px;
}
</style>
